package com.woohua.thread.pool;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/***
 * @title ThreadPoolExecutorDemo
 * @description
 * @author woo hua
 * @version 1.0.0
 * @create 2023/3/17 17:15
 **/
public class ThreadPoolExecutorDemo {

    public static void main(String[] args) {
        // 任务队列容量
        final int QUEUE_CAPACITY = 20;
        // LinkedBlockingDeque 双端阻塞队列
        BlockingQueue<Runnable> runnableBlockedQueue = new LinkedBlockingDeque<>(QUEUE_CAPACITY);

        // 创建线程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(4, 10, 60, TimeUnit.SECONDS, runnableBlockedQueue);

        int taskNo = 0;
        int queueSize = 0;

        while (true) {
            // 随机生成任务数
            int taskNum = getTaskNum();

            for (int i = 0; i < taskNum; i++) {
                taskNo++;

                //队列未满则提交新任务
                if(queueSize < QUEUE_CAPACITY) {
                    executor.execute(new Worker("Task" + taskNo));
                }else {
                    // 队列满了，则等待一会重试， 注意：如果队列满了还提交任务会因为超出队列容量而报错
                    while (true) {
                        sleep(200);
                        queueSize = executor.getQueue().size();
                        if(queueSize < QUEUE_CAPACITY) {
                            executor.execute(new Worker("Task" + taskNo));
                            break;
                        }
                    }
                }
                queueSize = executor.getQueue().size();
            }
        }
    }

    private static void sleep(int millis) {
        try {
            TimeUnit.MILLISECONDS.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    // 随机生成一次执行的任务数
    private static int getTaskNum() {
        return ((int) (1 + Math.random() * (8 - 1 + 1)));
    }
}
